package com.godpaper.the3directs.util
{
	import com.godpaper.the3directs.views.components.GasketButton;
	
	import jp.dip.hael.gameai.graph.GraphEx;
	import jp.dip.hael.gameai.graph.searcher.BFS;
	import jp.dip.hael.gameai.graph.searcher.DFS;
	import jp.dip.hael.gameai.graph.searcher.Dijkstra;
	
	import mx.collections.ArrayCollection;
	
	/**
	 * 
	 * @author Knight-errant
	 * 
	 */	
	public class PositionTransactUtil
	{
		/**
		 * 
		 * @param target
		 * @return transacted positionIndex to positionArray
		 * 
		 */		
		public static function transactIndex2Array(target:int):Array
		{
			var result:Array = [];
			if(0<=target&&target<=14)
			{
				result = [target,0];
			}else if(target>14&&target<=27)
			{
				result = [target-14,1];
			}else if(target>27&&target<=38)
			{
				result = [target-26,2];
			}else if(target>38&&target<=47)
			{
				result = [target-36,3];
			}else if(target>47&&target<=54)
			{
				result = [target-44,4];
			}else if(target>54&&target<=59)
			{
				result = [target-50,5];
			}else if(target>59&&target<=62)		
			{
				result = [target-54,6];
			}else if(target>62)
			{
				result = [target-56,7];
			}
			return result;
		}
		/**
		 * 
		 * @param target
		 * @return transacted positionArray to positionIndex.
		 * 
		 */		
		public static function transactArray2Index(target:Array):int
		{
			var result:int = -1;
			switch(target[1])
			{
				case 0:
					result = target[0];
					break;
				case 1:
					result = target[0]+14;
					break;	
				case 2:
					result = target[0]+26;
					break;
				case 3:
					result = target[0]+36;
					break;
				case 4:
					result = target[0]+44;
					break;
				case 5:
					result = target[0]+50;
					break;
				case 6:
					result = target[0]+54;
					break;
				case 7:
					result = target[0]+56;
					break;	
				default:
					break;			
			}
			return result;
		}
		/**
		 * 
		 * @param target
		 * @return whetherRotate180Degree
		 * 
		 */		
		public static function whetherRotate180Degree(target:int):Boolean
		{
			var result:Boolean;
			if(0<=target&&target<=14)
			{
				result = target%2!=1;
			}else if(target>14&&target<=27)
			{
				result = target%2==1;
			}else if(target>27&&target<=38)
			{
				result = target%2!=1;
			}else if(target>38&&target<=47)
			{
				result = target%2==1;
			}else if(target>47&&target<=54)
			{
				result = target%2!=1;
			}else if(target>54&&target<=59)
			{
				result = target%2==1;
			}else if(target>59&&target<=62)		
			{
				result = target%2!=1;
			}else if(target>62)
			{
				result = target%2==1;
			}
			return result;
		}
		
		
		public static function doesThisThreeIsLinkable(adjacents:ArrayCollection,opposites:ArrayCollection,hypotenuses:ArrayCollection,graphEx:GraphEx):Boolean
		{
			//subroutines;
			var adjacent2opposite:int 	= doesAdjacents2OppositesIsLinkable(adjacents,opposites,hypotenuses,graphEx);
			var adjacent2hypotenuse:int = doesAdjacents2HypotenusesIsLinkable(adjacents,opposites,hypotenuses,graphEx);
			var opposite2hypotenuse:int = doesOpposites2HypotenusesIsLinkable(adjacents,opposites,hypotenuses,graphEx);
			
			if( adjacent2opposite==999 )
			{
				return true;
			}
			if( adjacent2hypotenuse==999 )
			{
				return true;
			}
			if( opposite2hypotenuse==999 )
			{
				return true;
			}
			
			return adjacent2opposite>=1 && adjacent2hypotenuse>=1 && opposite2hypotenuse>=1;
		}
		
		private static function doesAdjacents2OppositesIsLinkable(adjacents:ArrayCollection,opposites:ArrayCollection,hypotenuses:ArrayCollection,graphEx:GraphEx):int
		{
			var adjacentIndex:int;
			var oppositeIndex:int;
			var hypotenuseIndex:int;
			
			var adjacent2opposite:int;
			
			for(var a2o:int=0;a2o<adjacents.length;a2o++)
			{
				adjacentIndex = PositionTransactUtil.transactArray2Index( (adjacents.getItemAt( a2o ) as GasketButton).position );
				for(var o2a:int=0;o2a<opposites.length;o2a++)
				{
					oppositeIndex = PositionTransactUtil.transactArray2Index( (opposites.getItemAt( o2a ) as GasketButton).position );
					var dfsSearcher:DFS = new DFS(graphEx);
					if(adjacentIndex!=oppositeIndex)
					{
						trace("adjacentIndex:",adjacentIndex,"oppositeIndex:",oppositeIndex);
						dfsSearcher.search( adjacentIndex,oppositeIndex );
						if(dfsSearcher.path.length>0)
						{
							adjacent2opposite++;
							for(var p:int=0;p<dfsSearcher.path.length;p++)
							{
								trace("adjacent2opposite:",dfsSearcher.path[p].dump());
							}
						}
					}else
					{
						if(doesOpposites2HypotenusesIsLinkable(adjacents,opposites,hypotenuses,graphEx))
						{
							adjacent2opposite = 999;//got adjacent peak to win!
						}
					}
				}
			}
			return adjacent2opposite;
		}
		
		private static function doesAdjacents2HypotenusesIsLinkable(adjacents:ArrayCollection,opposites:ArrayCollection,hypotenuses:ArrayCollection,graphEx:GraphEx):int
		{
			var adjacentIndex:int;
			var oppositeIndex:int;
			var hypotenuseIndex:int;
			
			var adjacent2hypotenuse:int;
			
			for(var a2h:int=0;a2h<adjacents.length;a2h++)
			{
				adjacentIndex = PositionTransactUtil.transactArray2Index( (adjacents.getItemAt( a2h ) as GasketButton).position );
				for(var h2a:int=0;h2a<hypotenuses.length;h2a++)
				{
					hypotenuseIndex = PositionTransactUtil.transactArray2Index( (hypotenuses.getItemAt( h2a ) as GasketButton).position );
					var bfsSearcher:BFS = new BFS(graphEx);
					if(adjacentIndex!=hypotenuseIndex)
					{
						trace("adjacentIndex:",adjacentIndex,"hypotenuseIndex:",hypotenuseIndex);
						bfsSearcher.search( adjacentIndex,hypotenuseIndex );
						if(bfsSearcher.path.length>0)
						{
							adjacent2hypotenuse++;
							for(var pp:int=0;pp<bfsSearcher.path.length;pp++)
							{
								trace("adjacent2hypotenuse:",bfsSearcher.path[pp].dump());
							}
						}
					}else
					{
						if(doesOpposites2HypotenusesIsLinkable(adjacents,opposites,hypotenuses,graphEx))
						{
							adjacent2hypotenuse = 999;//got hypotenuse peak to win!
						}
					}
						
				}
			}
			return adjacent2hypotenuse;
		}
		
		private static function doesOpposites2HypotenusesIsLinkable(adjacents:ArrayCollection,opposites:ArrayCollection,hypotenuses:ArrayCollection,graphEx:GraphEx):int
		{
			var adjacentIndex:int;
			var oppositeIndex:int;
			var hypotenuseIndex:int;
			
			var opposite2hypotenuse:int;
			
			for(var o2h:int=0;o2h<opposites.length;o2h++)
			{
				oppositeIndex = PositionTransactUtil.transactArray2Index( (opposites.getItemAt( o2h ) as GasketButton).position );
				for(var h2o:int=0;h2o<hypotenuses.length;h2o++)
				{
					hypotenuseIndex = PositionTransactUtil.transactArray2Index( (hypotenuses.getItemAt( h2o ) as GasketButton).position );
					var dijkstraSearcher:Dijkstra = new Dijkstra(graphEx);
					if(oppositeIndex!=hypotenuseIndex)
					{
						trace("oppositeIndex:",oppositeIndex,"hypotenuseIndex:",hypotenuseIndex);
						dijkstraSearcher.search( oppositeIndex,hypotenuseIndex );
						if(dijkstraSearcher.path.length>0)
						{
							opposite2hypotenuse++;
							for(var ppp:int=0;ppp<dijkstraSearcher.path.length;ppp++)
							{
								trace("opposite2hypotenuse:",dijkstraSearcher.path[ppp].dump());
							}
						}
					}else
					{
						if(doesAdjacents2HypotenusesIsLinkable(adjacents,opposites,hypotenuses,graphEx))
						{
							opposite2hypotenuse = 999;//got opposite peak to win!
						}
					}
				}
			}
			return opposite2hypotenuse;
		}
		
		
	}
}